package com.dashan.frontend.client.widgets;

import static com.dashan.Constants.FEMALE;
import static com.dashan.Constants.FRIENDNAME;
import static com.dashan.Constants.MALE;
import static com.dashan.Constants.USERNAME;

import java.util.Date;

import com.dashan.frontend.client.model.Position;
import com.dashan.frontend.client.util.DashanRequestBuilder;
import com.dashan.frontend.client.util.DashanXmlReader;
import com.dashan.frontend.client.util.GoogleMap;
import com.dashan.frontend.client.widgets.GeoGridPanel.GeoRecord;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.FloatFieldDef;
import com.gwtext.client.data.GroupingStore;
import com.gwtext.client.data.IntegerFieldDef;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.data.XmlReader;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.grid.CellMetadata;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GroupingView;
import com.gwtext.client.widgets.grid.Renderer;

public class FriendPanel extends Composite {
    private static final String GENDER = "gender";
    private static final String GROUPS = "groups";
    private static final String FRIEND_NAME = "friendName";
    private static final String GROUP = "group";
    private static final String LASTONLINE = "lastonline";
    private static final String DISTANCE = "distance";
    private static final String STATUS = "status";
    private static final String NICKNAME = "nickName";
    
    private Panel root = new Panel();
    
    private MainPanel main;
    private GeoGridPanel friendGrid;
    final RecordDef recordDef = new RecordDef(new FieldDef[] { 
            new StringFieldDef(USERNAME), 
            new StringFieldDef(NICKNAME),
            new StringFieldDef(GENDER),
            new StringFieldDef(STATUS), 
            new FloatFieldDef(DISTANCE),
            new IntegerFieldDef(LASTONLINE), 
            new StringFieldDef(GROUP)});
    public FriendPanel(MainPanel main) {
        this.main = main;
        
        Button b = new Button("reload");
        b.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, com.gwtext.client.core.EventObject e) {
                FriendPanel.this.onShow();
            }
        });
        root.add(b);
        initFriendPanel();
        initWidget(root);
    }
    
    private void initFriendPanel() {
        GroupingStore store = new GroupingStore(recordDef);
        friendGrid = new GeoGridPanel(main.getGoogleMap(), store);
        store.setGroupField(GROUP);
        
        ColumnConfig userName = new ColumnConfig("用户", NICKNAME, 1, true);

        userName.setWidth(50);
        ColumnConfig lastOnline = new ColumnConfig("上次更新", LASTONLINE, 1, true, new Renderer() {
            @Override
            public String render(Object value, CellMetadata cellMetadata, Record record,
                    int rowIndex, int colNum, Store store) {
                long lastOnline = record.getAsInteger(LASTONLINE);
                String res = " 之前";
                lastOnline /= 1000 * 60;
                if (lastOnline != 0) {
                    res = (lastOnline % 60) + "分" + res;
                    lastOnline /= 60;
                }
                if (lastOnline != 0) {
                    res = (lastOnline % 24) + "小时" + res;
                    lastOnline /= 24;
                }
                if (lastOnline != 0) {
                    res = (lastOnline) + "天" + res;
                }
                return res;
            }
        });
        lastOnline.setWidth(50);

        ColumnConfig distance = new ColumnConfig("距离", DISTANCE, 1, true, new Renderer() {
            @Override
            public String render(Object value, CellMetadata cellMetadata, Record record,
                    int rowIndex, int colNum, Store store) {
                return record.getAsString(DISTANCE);
            }
        });
        distance.setWidth(30);
        
        ColumnModel columnModel = 
            new ColumnModel(new ColumnConfig[] {userName, lastOnline, distance});
        friendGrid.setColumnModel(columnModel);

        friendGrid.setHeight(500);
        friendGrid.setWidth(275);
        friendGrid.setMargins(10, 0, 0, 0);
        
        GroupingView view = new GroupingView() {
            public String getRowClass(Record record, int index,
                    final com.gwtext.client.widgets.grid.RowParams rowParams, Store store) {
                rowParams.setBody(record.getAsString(STATUS));
                String genderClass = "";
                if (record.getAsString(GENDER) != null) {
                    if (record.getAsString(GENDER).compareTo(FEMALE) == 0) {
                        genderClass = "female_row";
                    } else if (record.getAsString(GENDER).compareTo(MALE) == 0) {
                        genderClass = "male_row";
                    }
                }
                return "x-grid3-row-expanded " + genderClass;
            };
        };
        view.setGroupTextTpl("{text} ({[values.rs.length]} {[values.rs.length > 1 ? \"Items\" : \"Item\"]})"); 
        
        
        view.setForceFit(true);
        view.setEnableRowBody(true);
        friendGrid.setView(view);
        
        root.add(friendGrid);
    }
    
    private void loadFriendList() {
        friendGrid.clearData();
        DashanRequestBuilder builder = new DashanRequestBuilder("/getfriendlist");
        builder.addUserParam();
        try {
            builder.sendRequest(new RequestCallback() {
                
                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Response.SC_OK == response.getStatusCode()) {
                        Record[] res = DashanXmlReader.fetchFromXml(response.getText(), 
                                new XmlReader("friend", 
                                new RecordDef(new FieldDef[] {
                                        new StringFieldDef(FRIEND_NAME),
                                        new StringFieldDef(GROUPS)
                        }
                        )));
                        
                        for (Record r : res) {
                            addFriendToList(r.getAsString(FRIEND_NAME), 
                                    r.getAsString(GROUPS).split(","));
                        }
                        
                    } else {
                        Window.alert(response.getStatusText());
                    }
                }
                
                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert(exception.getMessage());
                }
            });
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        }
    }


    private void addFriendToList(final String friendName, final String[] groups) {
        DashanRequestBuilder builder = new DashanRequestBuilder("/getuser");
        builder.addUserParam();
        builder.addParameter(FRIENDNAME, friendName);
        final long now = new Date().getTime();
        try {
            builder.sendRequest(new RequestCallback() {
                
                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Response.SC_OK == response.getStatusCode()) {

                        Record[] records = DashanXmlReader.fetchFromXml(response.getText(), 
                                new XmlReader("user", new RecordDef(
                                        new FieldDef[] {new StringFieldDef(NICKNAME), 
                                                        new StringFieldDef(STATUS),
                                                        new StringFieldDef(GENDER)})));
                        Record[] positions = DashanXmlReader.fetchFromXml(response.getText(), 
                                new XmlReader("position", new RecordDef(
                                        new FieldDef[] {new StringFieldDef("lng_lat_acc"), 
                                                new StringFieldDef("timestamp_long")})));

                        
                        if (records.length  == 1) {
                            Marker m;
                            long lastUpdate = 0;
                            if (positions.length != 1) {
                                m = null;
                            } else {
                                Record p = positions[0];
                                
                                Position pos = new Position(p.getAsString("lng_lat_acc"), 
                                        new Date(Long.parseLong(p.getAsString("timestamp_long"))));
                                MarkerOptions opt = MarkerOptions.newInstance(GoogleMap.ICON);
                                m = new Marker(LatLng.newInstance(pos.getLatitude(), pos
                                        .getLongitude()), opt);
                                lastUpdate = now - pos.getTimestamp().getTime();
                            }
                            Record r = records[0];
                            
                            for (String g : groups) {
                                Record record = recordDef.createRecord(new Object[] { 
                                        friendName, 
                                        r.getAsString(NICKNAME),
                                        r.getAsString(GENDER),
                                        r.getAsString(STATUS),
                                        //current position - b.getPosistion;
                                        100.3, 
                                        lastUpdate, 
                                        g});
                                
                                friendGrid.addGeoRecord(new GeoRecord(record, m));
                            }
                        } else {
                            Window.alert("Response Error!");
                        }
                    } else {
                        Window.alert(response.getText());
                    }
                }

                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert("Fail to get resopnse");
                }
            });
        } catch (RequestException e) {
            Window.alert("Fail to get resopnse");
            e.printStackTrace();
        }

    }
    
    public void onShow() {
        loadFriendList();
    }
}
